package com.ptmall.app.net.base;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.ptmall.app.App;
import com.ptmall.app.R;
import com.ptmall.app.net.HttpMethods;
import com.ptmall.app.utils.NetWorkUtils;

import java.lang.reflect.Type;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;

/**
 * Created by xuchaochao on 2017/4/7.
 * 网络请求model封装 Base类
 */

public class HttpDataRepositoryBase {

    private Context mContext = App.getInstance().getApplicationContext();
    protected HttpMethods mHttpMethods = HttpMethods.getInstance();
    protected Retrofit mRetrofit = HttpMethods.getInstance().getRetrofit();

    private static JsonSerializer<Number> numberJsonSerializer = new JsonSerializer<Number>() {
        @Override
        public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext context) {
            String back = String.valueOf(src);
            if (back.endsWith(".0")) {
                back = back.substring(0, back.indexOf("."));
            }
            return new JsonPrimitive(back);
        }
    };

    private static Gson mGson = new GsonBuilder()
            .registerTypeAdapter(Integer.class, numberJsonSerializer)
            .registerTypeAdapter(Long.class, numberJsonSerializer)
            .registerTypeAdapter(Float.class, numberJsonSerializer)
            .registerTypeAdapter(Double.class, numberJsonSerializer)
            .create();

    protected <T> void toSubscribe(Observable<T> observable, Consumer consumer) {
        Consumer<Throwable> errorConsumer = new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {

                //判断网络状态
                Result<Throwable> errorResult = new Result<Throwable>();
                errorResult.setStatus(0);

                NetWorkUtils netWorkUtils = new NetWorkUtils();
                if (!netWorkUtils.isConnected()) {
                    errorResult.setInfo(mContext.getString(R.string.net_work_unconnected));
                } else {
                    if (throwable instanceof SocketTimeoutException) {//网络超时
                        errorResult.setInfo(mContext.getString(R.string.error_net_timeout));
                    } else if (throwable instanceof ConnectException) {//网络异常
                        errorResult.setInfo(mContext.getString(R.string.error_net_connect_ex));
                    } else {
                        errorResult.setInfo(mContext.getString(R.string.error_unknow));
                    }
                }
                consumer.accept(errorResult);

                //报告异常
                if (null != throwable) {
                    errorResult.setInfo(mContext.getString(R.string.error_unknow));
                    Log.i("xucc",throwable.getMessage().toString());
                }
            }
        };


        Action onComplete = new Action() {
            @Override
            public void run() throws Exception {
                Log.i("xucc","onComplete");
            }
        };
        Consumer<Disposable> onSubcribe = new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                Log.i("xucc","onSubcribe");
                NetWorkUtils netWorkUtils = new NetWorkUtils();
                if (!netWorkUtils.isConnected()) {
                    errorConsumer.accept(null);
                    disposable.dispose();
                    return;
                }
            }
        };


        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumer,errorConsumer,onComplete,onSubcribe);
    }
    protected <T> Disposable toSubscribe(Observable<ApiBaseData> observable, ApiNetResponse<T> response, TypeToken<T> typeToken) {

        //成功时回调
        Consumer<ApiBaseData> consumer = new Consumer<ApiBaseData>() {
            @Override
            public void accept(ApiBaseData tNetRequestResultBean) throws Exception {
                if (null != response && null != tNetRequestResultBean) {
                    /* dowloand 判断 */
                    if (tNetRequestResultBean.isDownload()) {
                        if (tNetRequestResultBean.getStatusCode() == 1 || tNetRequestResultBean.getStatusCode() == 2) {//下载成功或下载中
                            response.onDownload(mGson.fromJson(mGson.toJson(tNetRequestResultBean.getData()),
                                    typeToken.getType()), tNetRequestResultBean.getStatusCode());
                        } else {//下载失败
                            response.onDownload(null, tNetRequestResultBean.getStatusCode());
                            String info = TextUtils.isEmpty(tNetRequestResultBean.getInfo())?"处理失败":tNetRequestResultBean.getInfo();
                            response.processFaile(info, null, null);
                        }
                        return;
                    }

                    if (tNetRequestResultBean.isSuccess()) {

                        if (null != typeToken) {
                            try {

                                //T t = mGson.fromJson(mGson.toJson(tNetRequestResultBean.getData()), typeToken.getType());
                                if (null == tNetRequestResultBean.getData()) {
                                    response.onSuccess(null);
                                } else {
                                    response.onSuccess(mGson.fromJson(mGson.toJson(tNetRequestResultBean.getData()), typeToken.getType()));
                                }

                            } catch (JsonSyntaxException e ) {
                                response.processFaile(null, null, e);
                            }
                        } else {
                            response.onSuccess(null);
                        }
                    } else {
                        //Log.i("xucccccccccccccc",tNetRequestResultBean.getInfo()+"       ");
                        if(tNetRequestResultBean.getInfo()!=null&&tNetRequestResultBean.getInfo().equals("请重新登录")){
//                            MyAlertDialog myAlertDialog = new MyAlertDialog(mContext.getApplicationContext(),mContext.getString(R.string.accout_nocan));
//                            myAlertDialog.setonclick(new MyAlertDialog.Onclick() {
//                                @Override
//                                public void Yes() {
//                                    mContext.startActivity(LoginFragment.getIntent(mContext));
//                                }
//
//                                @Override
//                                public void No() {
//
//                                }
//                            });
//                            myAlertDialog.setNoBtnGone();
//                            myAlertDialog.show();

//                            ToastUtil.showToast(mContext.getString(R.string.accout_nocan));
//                            mContext.startActivity(LoginFragment.getIntent(mContext));
                        }
                        String info = TextUtils.isEmpty(tNetRequestResultBean.getInfo())?"处理失败":tNetRequestResultBean.getInfo();
                        /*
                        if (null != typeToken) {
                            try {
                                T t = mGson.fromJson(mGson.toJson(tNetRequestResultBean.getData()), typeToken.getType());
                                response.onFaile(info, t, null);
                            } catch (JsonSyntaxException e ) {
                                response.onFaile(info, null, e);
                            }
                        } else {
                            response.onFaile(info, null, null);
                        }
                        */
//                        if (tNetRequestResultBean.getCode() > 0) {
//                            info = tNetRequestResultBean.getCode() +"";
//                        }
                        try {
                            response.processFaile(info, mGson.fromJson(mGson.toJson(tNetRequestResultBean.getData()), typeToken.getType()), null);
                        } catch (Exception e) {
                            response.processFaile(info, null, null);
                        }

                    }
                }
            }
        };

        //请求异常时回调
        Consumer<Throwable> errorConsumer = new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                if (null != response) {
                    response.processFaile(null, null, throwable);
                }
            }
        };

        Action onComplete = new Action() {
            @Override
            public void run() throws Exception {
                if (null != response) {
                    response.onComplete();
                }
            }
        };
        Consumer<Disposable> onSubcribe = new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                response.onStart();
                if (!NetWorkUtils.isConnectedNet()) {
                    errorConsumer.accept(null);
                    disposable.dispose();
                    return;
                }
            }
        };


        return observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumer,errorConsumer,onComplete,onSubcribe);
    }


    private <T> Disposable toReportSubscribe(Observable<T> observable, ApiNetResponse<T> response) {

        //成功时回调
        Consumer<T> consumer = new Consumer<T>() {
            @Override
            public void accept(T tNetRequestResultBean) throws Exception {
                if (null != response) {
                    response.onSuccess(tNetRequestResultBean);
                }
            }
        };

        //请求异常时回调
        Consumer<Throwable> errorConsumer = new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                if (null != response) {
                    response.processFaile(null, null, throwable);
                }
            }
        };

        Action onComplete = new Action() {
            @Override
            public void run() throws Exception {
                if (null != response) {
                    response.onComplete();
                }
            }
        };
        Consumer<Disposable> onSubcribe = new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                response.onStart();
                if (!NetWorkUtils.isConnectedNet()) {
                    errorConsumer.accept(null);
                    disposable.dispose();
                    return;
                }
            }
        };
        return observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(consumer,errorConsumer,onComplete,onSubcribe);
    }

}
